import { useEffect, useMemo, useRef, useState, type FormEvent } from 'react'
import type { TouchEvent, MouseEvent } from 'react'
import { useInfiniteQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import dayjs from 'dayjs'

import { AnniversaryAPI, RelationshipAPI } from '../app/api'
import type { ApiAnniversary } from '../app/types'
import useCurrentUser from '../app/hooks/useCurrentUser'
import PageHeader from '../components/PageHeader'
import { FormField, Input, Select } from '../components/ui/Form'
import Button from '../components/ui/Button'
import { KebabMenu } from '../components/ui/Menu'
import Modal from '../components/Modal'
import { PencilSquareIcon, TrashIcon } from '@heroicons/react/24/outline'
import useConfirmDialog from '../components/ui/useConfirmDialog'

const PAGE_SIZE = 10

const AnniversariesPage = () => {
  if (typeof document !== 'undefined') document.title = '纪念日 · Love Notes'
  const queryClient = useQueryClient()
  const {
    data,
    isLoading,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['anniversaries', 'list'],
    initialPageParam: 0,
    queryFn: ({ pageParam = 0 }) => AnniversaryAPI.list({ limit: PAGE_SIZE, offset: pageParam }),
    getNextPageParam: (lastPage) => lastPage.next_offset ?? undefined,
  })
  const anniversaries = useMemo(() => data?.pages.flatMap((page) => page.items) ?? [], [data])
  const loadMoreRef = useRef<HTMLDivElement | null>(null)

  useEffect(() => {
    const node = loadMoreRef.current
    if (!node) return
    const observer = new IntersectionObserver(
      (entries) => {
        const [entry] = entries
        if (entry?.isIntersecting && hasNextPage && !isFetchingNextPage) {
          fetchNextPage()
        }
      },
      { rootMargin: '200px 0px 200px 0px' },
    )
    observer.observe(node)
    return () => observer.disconnect()
  }, [fetchNextPage, hasNextPage, isFetchingNextPage])

  const { data: currentUser } = useCurrentUser()

  const createMutation = useMutation({
    mutationFn: AnniversaryAPI.create,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['anniversaries', 'list'] }),
  })

  const inviteMutation = useMutation({
    mutationFn: RelationshipAPI.invite,
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['relationships'] }),
  })

  const [form, setForm] = useState({ name: '', date: '', reminder: 7, recurrence: 'yearly', isLunar: false, lunarDate: '', countdown: 'down' as 'down' | 'up' | 'both' })
  const [modalOpen, setModalOpen] = useState(false)
  const [editingId, setEditingId] = useState<number | null>(null)
  const [confirm, ConfirmDialog] = useConfirmDialog()
  const [activeActionId, setActiveActionId] = useState<number | null>(null)
  const hideTimerRef = useRef<number | null>(null)

  useEffect(() => {
    if (activeActionId === null) return
    if (hideTimerRef.current) window.clearTimeout(hideTimerRef.current)
    hideTimerRef.current = window.setTimeout(() => setActiveActionId(null), 3000)
    return () => {
      if (hideTimerRef.current) {
        window.clearTimeout(hideTimerRef.current)
        hideTimerRef.current = null
      }
    }
  }, [activeActionId])

  const hasActiveRelationship = Boolean(currentUser?.active_relationship_id)

  const upcoming = useMemo(
    () =>
      [...anniversaries]
        .map((item) => {
          const nextDate = (item as any).next_date || item.date
          const diffServer = (item as any).days_until
          const diff = typeof diffServer === 'number' ? diffServer : dayjs(nextDate).diff(dayjs(), 'day')
          return { item, diff, nextDate }
        })
        .sort((a, b) => a.diff - b.diff),
    [anniversaries],
  )

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    // 校验：公历需要 date；农历需要 lunarDate
    if (!form.name) return
    if (!form.isLunar && !form.date) return
    if (form.isLunar && !form.lunarDate) return

    const basePayload: any = {
      name: form.name,
      recurrence: form.recurrence,
      reminder_offset_days: form.reminder,
      is_lunar: form.isLunar,
      lunar_date_str: form.isLunar ? form.lunarDate || null : null,
      countdown_mode: form.countdown,
    }
    if (!form.isLunar && form.date) {
      basePayload.date = form.date
    }

    if (editingId) {
      await AnniversaryAPI.update(editingId, basePayload)
      await queryClient.invalidateQueries({ queryKey: ['anniversaries', 'list'] })
    } else {
      // 仅在公历时附带 date；农历可不附带
      const payload = (!form.isLunar && form.date) ? { ...basePayload, date: form.date } : basePayload
      await createMutation.mutateAsync(payload)
    }
    setForm({ name: '', date: '', reminder: 7, recurrence: 'yearly', isLunar: false, lunarDate: '', countdown: 'down' })
    setEditingId(null)
    setModalOpen(false)
  }

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Milestones"
        title="纪念日&仪式感"
        description="把值得纪念的瞬间写进时间线，提前设置提醒，让惊喜与仪式感更从容。"
        actions={
          !hasActiveRelationship ? (
            <button
              onClick={() => inviteMutation.mutate()}
              className="inline-flex items-center justify-center rounded-2xl border border-slate-200 bg-white px-4 py-2 text-xs font-semibold text-slate-600 transition hover:border-blush-200 hover:text-blush-500"
              disabled={inviteMutation.isPending}
            >
              {inviteMutation.isPending ? '生成中...' : '发送情侣邀请'}
            </button>
          ) : null
        }
      />

      <div className="flex justify-end">
        <Button size="sm" onClick={() => { setEditingId(null); setModalOpen(true) }}>添加纪念日</Button>
      </div>

      <Modal open={modalOpen} onClose={() => setModalOpen(false)} title={editingId ? '编辑纪念日' : '添加纪念日'}>
        <form className="mt-2 grid gap-3 lg:grid-cols-2" onSubmit={handleSubmit}>
          <FormField label="名称" required>
            <Input value={form.name} onChange={(e) => setForm((prev) => ({ ...prev, name: e.target.value }))} placeholder="第一次旅行" />
          </FormField>
          <FormField label={form.isLunar ? '农历日期' : '公历日期'} required>
            {form.isLunar ? (
              <Input value={form.lunarDate} onChange={(e) => setForm((p) => ({ ...p, lunarDate: e.target.value }))} placeholder="农历示例：正月初五" />
            ) : (
              <Input type="date" value={form.date} onChange={(e) => setForm((p) => ({ ...p, date: e.target.value }))} />
            )}
          </FormField>
          <FormField label="重复规则">
            <Select value={form.recurrence} onChange={(e) => setForm((p) => ({ ...p, recurrence: e.target.value }))}>
              <option value="once">仅一次</option>
              <option value="monthly">每月</option>
              <option value="yearly">每年</option>
              <option value="custom">自定义</option>
            </Select>
          </FormField>
          <FormField label="提前提醒（天）" hint="建议至少提前 7 天">
            <Input
              type="number"
              min={0}
              value={form.reminder}
              onChange={(e) => setForm((p) => ({ ...p, reminder: Number(e.target.value) }))}
            />
          </FormField>
          <FormField label="日期类型">
            <Select value={form.isLunar ? 'lunar' : 'solar'} onChange={(e) => setForm((p) => ({ ...p, isLunar: e.target.value === 'lunar' }))}>
              <option value="solar">公历</option>
              <option value="lunar">农历</option>
            </Select>
          </FormField>
          <FormField label="计时模式">
            <Select value={form.countdown} onChange={(e) => setForm((p) => ({ ...p, countdown: e.target.value as 'down' | 'up' | 'both' }))}>
              <option value="down">倒计时</option>
              <option value="up">正计时</option>
              <option value="both">同时显示</option>
            </Select>
          </FormField>
          <div className="lg:col-span-2 flex justify-end">
            <Button type="submit" size="sm" disabled={createMutation.isPending}>
              {createMutation.isPending ? '保存中...' : '保存'}
            </Button>
          </div>
        </form>
      </Modal>

      <section className="grid gap-4 md:grid-cols-2">
        {isLoading ? (
          <p className="text-sm text-slate-400">纪念日加载中...</p>
        ) : anniversaries.length === 0 ? (
          <p className="text-sm text-slate-400">暂无纪念日，先添加一条值得纪念的日子吧。</p>
        ) : (
          <>
            {upcoming.map(({ item, diff }) => (
              <AnniversaryCard
                key={item.id}
                anniversary={item}
                countdown={diff}
                showActions={activeActionId === item.id}
                onShowActions={() => setActiveActionId(item.id)}
                onHideActions={() => setActiveActionId(null)}
                onEdit={() => {
                  setActiveActionId(null)
                  setEditingId(item.id)
                  setForm({
                    name: item.name,
                    date: dayjs(item.date).format('YYYY-MM-DD'),
                    reminder: item.reminder_offset_days,
                    recurrence: item.recurrence,
                    isLunar: Boolean(item.is_lunar),
                    lunarDate: item.lunar_date_str || '',
                    countdown: (item.countdown_mode as 'down' | 'up' | 'both') || 'down',
                  })
                  setModalOpen(true)
                }}
                onDelete={async () => {
                  const confirmed = await confirm({
                    title: '删除纪念日',
                    description: '删除后无法恢复，确认要删除该纪念日吗？',
                    confirmText: '确定删除',
                  })
                  if (!confirmed) return
                  await AnniversaryAPI.remove(item.id)
                  setActiveActionId(null)
                  await queryClient.invalidateQueries({ queryKey: ['anniversaries', 'list'] })
                }}
              />
            ))}
            <div ref={loadMoreRef} className="h-6 md:col-span-2" />
            {isFetchingNextPage ? (
              <p className="md:col-span-2 text-center text-xs text-slate-400">加载更多中...</p>
            ) : null}
            {!hasNextPage && anniversaries.length > 0 ? (
              <p className="md:col-span-2 text-center text-xs text-slate-300">没有更多纪念日了</p>
            ) : null}
          </>
        )}
      </section>
      <ConfirmDialog />
    </div>
  )
}

export default AnniversariesPage

type AnniversaryCardProps = {
  anniversary: ApiAnniversary
  countdown: number
  showActions: boolean
  onShowActions: () => void
  onHideActions: () => void
  onEdit: () => void
  onDelete: () => void
}

const AnniversaryCard = ({
  anniversary,
  countdown,
  showActions,
  onShowActions,
  onHideActions,
  onEdit,
  onDelete,
}: AnniversaryCardProps) => {
  const longPressTimer = useRef<number | null>(null)
  const longPressTriggered = useRef(false)

  const clearTimer = () => {
    if (longPressTimer.current) {
      window.clearTimeout(longPressTimer.current)
      longPressTimer.current = null
    }
  }

  const handleTouchStart = () => {
    longPressTriggered.current = false
    clearTimer()
    longPressTimer.current = window.setTimeout(() => {
      longPressTriggered.current = true
      onShowActions()
    }, 350)
  }

  const handleTouchMove = () => {
    clearTimer()
  }

  const handleTouchEnd = (event: TouchEvent) => {
    clearTimer()
    if (longPressTriggered.current) {
      event.preventDefault()
      longPressTriggered.current = false
    }
  }

  const handleContextMenu = (event: MouseEvent) => {
    event.preventDefault()
    onShowActions()
  }

  const handleCardClick = () => {
    if (showActions) {
      onHideActions()
    }
  }

  const countdownLabel = countdown >= 0 ? `还有 ${countdown} 天` : '已过'

  return (
    <article
      onContextMenu={handleContextMenu}
      onTouchStart={handleTouchStart}
      onTouchEnd={handleTouchEnd}
      onTouchMove={handleTouchMove}
      onClick={handleCardClick}
      className="relative surface-card p-6"
    >
      {showActions ? (
        <div
          className="absolute right-4 top-4 z-20 flex items-center gap-2 rounded-full bg-white/95 px-2 py-1 shadow-md ring-1 ring-slate-200"
          onClick={(event) => event.stopPropagation()}
        >
          <button
            className="flex h-8 w-8 items-center justify-center rounded-full text-slate-500 transition hover:text-slate-700"
            onClick={(event) => {
              event.stopPropagation()
              onHideActions()
              onEdit()
            }}
          >
            <PencilSquareIcon className="h-4 w-4" />
          </button>
          <span className="h-6 w-px bg-slate-200" aria-hidden />
          <button
            className="flex h-8 w-8 items-center justify-center rounded-full text-red-500 transition hover:text-red-600"
            onClick={(event) => {
              event.stopPropagation()
              onHideActions()
              onDelete()
            }}
          >
            <TrashIcon className="h-4 w-4" />
          </button>
        </div>
      ) : null}
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <h3 className="truncate text-base font-semibold">{anniversary.name}</h3>
          <p className="mt-1 text-xs opacity-80">日期：{dayjs(anniversary.date).format('YYYY-MM-DD')}</p>
          {(anniversary as any).next_date ? (
            <p className="mt-1 text-xs opacity-70">下一次：{dayjs((anniversary as any).next_date).format('YYYY-MM-DD')}</p>
          ) : null}
        </div>
        <KebabMenu
          items={[
            { label: '编辑', onSelect: onEdit },
            { label: '删除', danger: true, onSelect: onDelete },
          ]}
        />
      </div>
      <div className="mt-3 flex items-center justify-between">
        <span className="inline-flex items-center gap-1 rounded-full border border-white/20 bg-white/10 px-3 py-1 text-xs font-medium">
          {countdownLabel}
        </span>
        <span className="text-[11px] opacity-70">提前 {anniversary.reminder_offset_days} 天提醒</span>
      </div>
    </article>
  )
}
